home *** CD-ROM | disk | FTP | other *** search
- #include "WolfDef.h"
- #include <string.h>
- #include <math.h>
-
- #define DOORPIC 59
-
- /* Scale ranges from 0xffff (one tile == 512 pixels high) down to 0x100 (one tile == 2 pixels) */
-
- savenode_t *nodes;
- saveseg_t *pwallseg; /* pushwall in motion*/
-
- /*
- ================================================
-
- MATH ROUTINES
-
- ================================================
- */
-
- /* -8.8 * -0.8 = -8.8*/
- fixed_t FixedByFrac (fixed_t a, fixed_t b)
- {
- fixed_t c;
- c = ((long)a * (long)b)>>FRACBITS;
- return c;
- }
-
- /* -8.8 * -0.8 = -8.8*/
- fixed_t SUFixedMul (fixed_t a, ufixed_t b)
- {
- fixed_t c;
- c = ((long)a * (long)b)>>FRACBITS;
- return c;
- }
-
- /* -8.8 / -8.8 = -8.8*/
- fixed_t FixedDiv (fixed_t a, fixed_t b)
- {
- a = (long)(((long)a<<FRACBITS) / (long)b);
- return a;
- }
-
- /**********************************
-
- Return the x coord for a sprite
-
- **********************************/
-
- fixed_t R_TransformX(fixed_t x,fixed_t y)
- {
- fixed_t gxt,gyt;
- gxt = FixedByFrac(x,viewsin);
- gyt = FixedByFrac(y,viewcos);
- return gxt-gyt;
- }
-
- /**********************************
-
- Return the scale factor for a sprite
-
- **********************************/
-
- fixed_t R_TransformZ(fixed_t x,fixed_t y)
- {
- fixed_t gxt,gyt;
- gxt = FixedByFrac(x,viewcos);
- gyt = FixedByFrac(y,viewsin);
- return gxt+gyt;
- }
-
- /**********************************
-
- Return the scale factor from a 64k range angle
-
- **********************************/
-
- Word ScaleFromGlobalAngle(int visangle,int distance)
- {
- fixed_t tz;
-
- Word anglea, angleb;
- Word sinea, sineb;
-
- visangle >>= ANGLETOFINESHIFT;
- anglea = (FINEANGLES/4 + (visangle-centerangle))&(FINEANGLES/2-1);
- angleb = (FINEANGLES/4 + (visangle-normalangle))&(FINEANGLES/2-1);
- sinea = finesine[anglea]; /* bothe sines are always positive*/
- sineb = finesine[angleb];
-
- tz = ((long)distance * sinea) / sineb;
-
- if (tz>=MAXZ) { /* Make sure it's not too big... */
- tz = MAXZ-1;
- }
- return scaleatzptr[tz]; /* Return the size */
- }
-
- /**********************************
-
- The automap has to be done in quadrants for various reasons
-
- **********************************/
-
- void DrawAutomap(Word tx,Word ty)
- {
- Word i, tile;
- saveseg_t *seg;
- Word x,y,xstep,ystep,count;
- Word min,max;
- Word maxtx, maxty;
- Word NodeCount;
-
- NodeCount = MapPtr->numnodes;
- maxtx = tx+(SCREENWIDTH/16);
- maxty = ty+(SCREENHEIGHT/16);
- seg = (saveseg_t *)nodes;
- i = 0;
- do {
- if ( (seg->dir & (DIR_SEGFLAG|DIR_SEENFLAG)) == (DIR_SEGFLAG|DIR_SEENFLAG) ) {
- min = (seg->min-1)>>1;
- max = (seg->max+3)>>1;
-
- switch (seg->dir&3) {
- case di_north:
- x = (seg->plane-1)>>1;
- y = min;
- xstep = 0;
- ystep = 1;
- break;
- case di_south:
- x = seg->plane>>1;
- y = min;
- xstep = 0;
- ystep = 1;
- break;
- case di_east:
- y = (seg->plane-1)>>1;
- x = min;
- xstep = 1;
- ystep = 0;
- break;
- case di_west:
- y = seg->plane>>1;
- x = min;
- xstep = 1;
- ystep = 0;
- break;
- }
-
- for (count=max-min ; count ; --count,x+=xstep,y+=ystep) {
- if (x < tx || x >= maxtx || y < ty || y>=maxty) {
- continue;
- }
- tile = tilemap[y][x];
- if (tile & TI_DOOR) {
- tile = 59 /*(seg->dir&1) + 30*/;
- } else if (tile & TI_PUSHWALL) {
- if (ShowPush) {
- tile = 64;
- } else {
- tile = textures[y][x];
- }
- } else {
- tile = MapPtr->tilemap[y][x];
- if (! (tile&0x80) ) {
- continue; /* not a solid tile*/
- }
- tile = textures[y][x];
- }
- DrawSmall(x-tx,y-ty,tile); /* Draw the tile on the screen */
- }
- }
- ++seg;
- } while (++i<NodeCount);
- x = viewx>>8;
- y = viewy>>8;
- if (x >= tx && x < maxtx && y >= ty && y<maxty) {
- DrawSmall(x-tx,y-ty,64); /* Draw BJ's face here */
- }
- BlastScreen();
- }
-
- /**********************************
-
- Init my math tables for the current view
-
- **********************************/
-
- #define PI 3.141592657
-
- Boolean StartupRendering(Word NewSize)
- {
- #ifdef __MAC__
- int i;
- Word minz;
- int x;
- float a, fv;
- long t;
- LongWord focallength;
- Word j;
- Word *ScalePtr;
- #endif
-
- if (NewSize == MathSize) { /* Already loaded? */
- return TRUE;
- }
-
- #ifdef __MAC__ /* Only the mac version will calculate the tables */
-
- /* generate scaleatz*/
-
- ScalePtr = scaleatzptr;
- minz = PROJECTIONSCALE/MAXFRAC; /* What's the largest index */
- for (j=0;j<=minz;j++) {
- ScalePtr[j] = MAXFRAC; /* Fill in the overflow area (No longs) */
- }
- do { /* Calculate the rest */
- ScalePtr[j] = PROJECTIONSCALE/j; /* Create whole numbers */
- } while (++j<MAXZ);
-
- /* viewangle tangent table*/
-
- if (MathSize==-1) { /* Only needs to be done once */
- i = 0;
- do {
- a = (i-FINEANGLES/4+0.1)*PI*2/FINEANGLES;
- fv = 256*tan(a);
- if (fv>0x7fff) {
- t = 0x7fff;
- } else if (fv<-0x7fff) {
- t = -0x7fff;
- } else {
- t = fv;
- }
- finetangent[i] = t;
- } while (++i<FINEANGLES/2);
-
- /* finesine table*/
-
- i = 0;
- do {
- a = (i+0.0)*PI*2/FINEANGLES;
- t = 256*sin(a);
- if (t>255) {
- t = 255;
- }
- if (t<1) {
- t = 1;
- }
- finesine[i] = t;
- } while (++i<FINEANGLES/2);
- }
-
- /* use tangent table to generate viewangletox*/
-
- /* calc focallength so FIELDOFVIEW angles covers SCREENWIDTH */
-
- focallength = (SCREENWIDTH/2)<<FRACBITS/finetangent[FINEANGLES/4+FIELDOFVIEW/2];
- i = 0;
- do {
- t = ((long) finetangent[i]*(long)focallength)>>FRACBITS;
- t = (int)SCREENWIDTH/2 - t;
- if (t < -1) {
- t = -1;
- } else if (t>(int)SCREENWIDTH+1) {
- t = SCREENWIDTH+1;
- }
- viewangletox[i] = t;
- } while (++i<FINEANGLES/2);
-
- /* scan viewangletox[] to generate xtoviewangle[]*/
-
- x = 0;
- do {
- i = 0;
- while (viewangletox[i]>=x) {
- i++;
- }
- xtoviewangle[x] = i-FINEANGLES/4-1;
- } while (++x<=SCREENWIDTH);
-
- /* take out the fencepost cases from viewangletox*/
-
- for (i=0 ; i<FINEANGLES/2 ; i++) {
- t = SUFixedMul (finetangent[i], focallength);
- t = (int)SCREENWIDTH/2 - t;
- if (viewangletox[i] == -1) {
- viewangletox[i] = 0;
- } else if (viewangletox[i] == SCREENWIDTH+1) {
- viewangletox[i] = SCREENWIDTH;
- }
- }
-
- #if 0 /* Should I save these tables? */
- if (!NewSize) {
- SaveJunk(scaleatzptr,sizeof(Word)*MAXZ);
- SaveJunk(finetangent,sizeof(short)*FINEANGLES/2);
- SaveJunk(finesine,sizeof(short)*FINEANGLES/2);
- SaveJunk(viewangletox,sizeof(short)*FINEANGLES/2);
- SaveJunk(xtoviewangle,sizeof(short)*(SCREENWIDTH+1));
- GoodBye();
- }
- #endif
-
- #else
- /* All other versions load the tables from disk (MUCH FASTER!!) */
- if (MathSize==-1) {
- finetangent = LoadAResource(rFineTangent);
- finesine = LoadAResource(rFineSine);
- }
- scaleatzptr = LoadAResource(rScaleAtZ);
- viewangletox = LoadAResource(rViewAngleToX);
- xtoviewangle = LoadAResource(rXToViewAngle);
- #endif
-
- clipshortangle = xtoviewangle[0]<<ANGLETOFINESHIFT; /* Save leftmost angle for view */
- clipshortangle2 = clipshortangle*2; /* Double the angle for constant */
-
- /* textures for doors stay the same across maps*/
-
- memset(textures[128],DOORPIC+4,MAPSIZE); /* door side*/
- memset(textures[129],DOORPIC+0,MAPSIZE); /* regular door*/
- memset(textures[130],DOORPIC+1,MAPSIZE); /* lock 1*/
- memset(textures[131],DOORPIC+2,MAPSIZE); /* lock 2*/
- memset(textures[132],DOORPIC+3,MAPSIZE); /* elevator*/
- ReleaseScalers(); /* Release any compiled scalers */
- if (!SetupScalers()) { /* Redo any scalers */
- return FALSE;
- }
- MathSize = NewSize;
- return TRUE;
- }
-
- /**********************************
-
- Alert the rendering engine about a new map
-
- **********************************/
-
- void NewMap(void)
- {
- Word x,y, tile;
- Byte *src;
- #ifdef __BIGENDIAN__
- savenode_t *FixPtr;
- #endif
- memset(textures,0xff,128*64); /* clear array so pushwall spawning can insert*/
- /* texture numbers in empty spots*/
- src = &MapPtr->tilemap[0][0];
- y = 0;
- do {
- x = 0;
- do {
- tile = *src++;
- if (tile&TI_BLOCKMOVE) { /* blocking?*/
- tile = ((tile&0x3f)-1)*2;
- textures[MAPSIZE+x][y] = tile + 1; /* Use the dark shape */
- textures[y][x] = tile; /* Use the light shape */
- }
- } while (++x<MAPSIZE);
- } while (++y<MAPSIZE);
-
- nodes = (savenode_t *)((Byte *)MapPtr + MapPtr->nodelistofs);
- #ifdef __BIGENDIAN__
- y = MapPtr->numnodes;
- FixPtr = nodes;
- while (y) {
- FixPtr->children[0] = SwapUShort(FixPtr->children[0]); /* Swap endian on all offsets */
- FixPtr->children[1] = SwapUShort(FixPtr->children[1]);
- ++FixPtr;
- --y;
- }
- #endif
- pwallseg = 0; /* No pushwalls in progress */
-
- }
-
- /**********************************
-
- Set up my pushwall record so the BSP records will follow
-
- **********************************/
-
- void StartPushWall(void)
- {
- Word i;
- Word segdir,segplane,segmin;
- saveseg_t *SavePtr; /* Temp pointer */
-
- pwallseg = 0; /* No pushwalls in progress */
-
- switch (PushWallRec.pwalldir) { /* Which direction? */
- case CD_NORTH:
- segmin = PushWallRec.pwallx<<1; /* Minimum segment */
- segplane = (PushWallRec.pwally+1)<<1; /* y facing plane */
- segdir = di_east; /* Point east */
- break;
- case CD_EAST:
- segplane = PushWallRec.pwallx<<1; /* Minimum segment */
- segmin = PushWallRec.pwally<<1;
- segdir = di_south; /* Point south */
- break;
- case CD_SOUTH:
- segmin = PushWallRec.pwallx<<1;
- segplane = PushWallRec.pwally<<1;
- segdir = di_west; /* Point west */
- break;
- case CD_WEST:
- segplane = (PushWallRec.pwallx+1)<<1;
- segmin = PushWallRec.pwally<<1;
- segdir = di_north; /* Point north */
- }
-
- SavePtr = (saveseg_t *)nodes; /* Init pointer to the nodes */
- i = MapPtr->numnodes; /* Get the node count */
- if (i) { /* Maps MUST have nodes */
- do {
- if ((SavePtr->dir & DIR_SEGFLAG) && /* Segmented? */
- ((SavePtr->dir & 3) == segdir) && /* Proper side? */
- (SavePtr->plane == segplane) && /* Proper plane? */
- (SavePtr->min == segmin) ) { /* Proper segment */
- pwallseg = SavePtr; /* Save the segment */
- return; /* Exit */
- }
- ++SavePtr; /* Next index */
- } while (--i); /* Count down */
- }
- }
-
- /**********************************
-
- Mark a pushwall BSP segment as disabled
-
- **********************************/
-
- void AdvancePushWall(void)
- {
- if (pwallseg) { /* Failsafe */
- pwallseg->dir |= DIR_DISABLEDFLAG; /* Mark the pushwall as disabled */
- }
- }
-
- /**********************************
-
- Render the entire 3-D view
-
- **********************************/
-
- void RenderView(void)
- {
-
- Word frame;
-
- centerangle = gamestate.viewangle<<GAMEANGLETOFINE; /* 512 to 2048 */
- centershort = centerangle<<ANGLETOFINESHIFT; /* 2048 to 64k */
- viewsin = sintable[gamestate.viewangle]; /* Get the basic sine */
- viewcos = costable[gamestate.viewangle]; /* Get the basic cosine */
- memset(areavis, 0, sizeof(areavis)); /* No areas are visible */
- ClearClipSegs(); /* Clip first seg only to sides of screen */
- IO_ClearViewBuffer(); /* Erase to ceiling / floor colors*/
-
- bspcoord[BSPTOP] = 0; /* The map is 64*64 */
- bspcoord[BSPBOTTOM] = 64*FRACUNIT;
- bspcoord[BSPLEFT] = 0;
- bspcoord[BSPRIGHT] = 64*FRACUNIT;
-
- RenderBSPNode(0); /* traverse the BSP tree from the root */
- DrawSprites(); /* sort all the sprites in any of the rendered areas*/
- DrawTopSprite(); /* draw game over sprite on top of everything*/
-
- if (!NoWeaponDraw) { /* Don't draw the weapon? */
- frame = gamestate.attackframe;
- if (frame == 4) {
- frame = 1; /* drop back frame*/
- }
- IO_AttackShape(gamestate.weapon*4 + frame); /* Draw the gun shape */
- }
- IO_DisplayViewBuffer(); /* blit to screen */
- }
-